import Koa from 'koa'
import Router from '@koa/router'
import logger from 'koa-logger'
import serve from 'koa-static'
import { bodyParser } from '@koa/bodyparser'
import { jwtAuth } from './server/middleware/auth.js'
import helmet from 'koa-helmet'
import mount from 'koa-mount'
import { join, dirname } from 'node:path'
import { fileURLToPath } from 'node:url'
import { createWriteStream, mkdirSync } from 'node:fs'
import { format } from 'node:util'

import './server/utils/envLoad.js'
const __dirname = dirname(fileURLToPath(import.meta.url))

import authRouter from './server/routes/auth.js'
import dataRouter from './server/routes/data.js'
import fileRouter from './server/routes/file.js'
import usersRouter from './server/routes/users.js'
import swaggerRouter from './server/routes/swagger.js'
import swagger from './server/routes/swagger.js'

// log file
mkdirSync(join(__dirname, './logs'), { recursive: true })
const logFile = createWriteStream(join(__dirname, `./logs/log ${new Date().toLocaleString('zh-CN').replace(/[\/:]/gi, '-')}.txt`), { flags: 'w' })
console.log = (...message) => {
  logFile.write(format(new Date().toLocaleString()) + ' ')
  logFile.write(format(...message) + '\n')
  process.stdout.write(format(...message) + '\n')
}

const logErrorFile = createWriteStream(join(__dirname, './logs/ErrorLog.txt'), { flags: 'w' })
console.error = (...message) => {
  logErrorFile.write('\n' + format(new Date().toLocaleString()) + '\n')
  logErrorFile.write(format(...message) + '\n')
  process.stderr.write(format(...message) + '\n')
}
console.error(`Start server at ${new Date().toLocaleString()}`)

process
  .on('unhandledRejection', (reason, promise) => {
    console.error('Unhandled Rejection at:', promise, 'reason:', reason)
  })
  .on('uncaughtException', err => {
    console.error(err, 'Uncaught Exception thrown')
  })

// log end

const app = new Koa()
const router = new Router()

// 全局错误处理中间件，避免返回500
app.use(async (ctx, next) => {
  try {
    await next()
  } catch (err) {
    console.error('Global error captured:', err && (err.stack || err.message || err))
    ctx.status = 200
    ctx.body = {
      success: false,
      message: '服务器内部错误',
      error: String(err && (err.message || err))
    }
  }
})

app.use(async (ctx, next) => {
  // 基本CORS头设置
  ctx.set('Access-Control-Allow-Origin', '*')
  ctx.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
  ctx.set('Access-Control-Allow-Headers', 'Content-Type, Authorization')
  
  // 处理预检请求
  if (ctx.method === 'OPTIONS') {
    ctx.status = 200
    return
  }
  
  process.stdout.write(`Request from: ${ctx.request.ip} at ${new Date().toLocaleString()}\n`)
  await next()
})

app.use(logger((str) => {
  process.stdout.write(str + '\n')
}))


app.use(helmet({
  contentSecurityPolicy: false,
  hsts: false,
  crossOriginOpenerPolicy: false,
  originAgentCluster: false
}))
app.use(bodyParser({
  jsonLimit: '32mb',
  textLimit: '32mb'
}))

app.use(serve(join(__dirname, './dist')))
app.use(mount('/swagger', serve(join(__dirname, './swagger-dist'))))

router.use('/auth', authRouter.routes())
// router.use('/data', dataRouter.routes())
router.use('/data', jwtAuth, dataRouter.routes())
router.use('/swagger', swagger.routes())
router.use('/api/file', fileRouter.routes())
router.use('/api/users', jwtAuth, usersRouter.routes())
router.use('/swagger', swaggerRouter.routes())
app.use(router.routes())

const port = +process.env.PORT || 9002
const host = '0.0.0.0' // 绑定到所有网络接口，允许外部访问

app.listen(port, host, () => {
  console.log(`Server is running on http://${host}:${port}`)
  console.log(`Server started at ${new Date().toLocaleString()}`)
})